package com.woniuxy.life.core.exception;

import com.google.common.collect.ImmutableMap;
import com.woniuxy.life.core.api.CommonResult;
import com.woniuxy.life.core.api.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionAdvice {
    private static ImmutableMap
            <Class<? extends Throwable>, ResultCode> immutableMap;
    private static ImmutableMap.Builder
            <Class<? extends Throwable>, ResultCode> builder
            =ImmutableMap.builder();
    static {
        builder.put(HttpMessageNotReadableException.class,ResultCode.VALIDATE_FAILED);
        builder.put(HttpRequestMethodNotSupportedException.class,ResultCode.VALIDATE_METHOD_FAILED);
    }


    /**
     * 处理参数校验异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult methodArgumentNotValidExceptionHandler
    (MethodArgumentNotValidException e){
        log.error("MethodArgumentNotValidException:",e);
        ObjectError error = e.getBindingResult().getAllErrors().get(0);
        return CommonResult.methodArgumentValidFailed(error.getDefaultMessage());
    }


    /**
     *处理未知异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    public CommonResult exceptionHandler(Exception e) {
        log.error("Exception:" + e);
        if (immutableMap == null) {
            immutableMap = builder.build();
        }
        ResultCode resultCode = immutableMap.get(e.getClass());
        if (resultCode != null) {
            return CommonResult.failed(resultCode.getCode(),
                    resultCode.getMessage());
        }
        return CommonResult.failed();
    }
}
